home *** CD-ROM | disk | FTP | other *** search
/ Games of Daze / Infomagic - Games of Daze (Summer 1995) (Disc 1 of 2).iso / x2ftp / msdos / misc / wt004wc / fixed.h < prev    next >
Encoding:
C/C++ Source or Header  |  1994-05-27  |  4.2 KB  |  154 lines

  1. /*
  2. **  wt -- a 3d game engine
  3. **
  4. **  Copyright (C) 1994 by Chris Laurel
  5. **  email:  claurel@mr.net
  6. **  snail mail:  Chris Laurel, 5700 W Lake St #208,  St. Louis Park, MN  55416
  7. **
  8. **  This program is free software; you can redistribute it and/or modify
  9. **  it under the terms of the GNU General Public License as published by
  10. **  the Free Software Foundation; either version 2 of the License, or
  11. **  (at your option) any later version.
  12. **
  13. **  This program is distributed in the hope that it will be useful,
  14. **  but WITHOUT ANY WARRANTY; without even the implied warranty of
  15. **  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  16. **  GNU General Public License for more details.
  17. **
  18. **  You should have received a copy of the GNU General Public License
  19. **  along with this program; if not, write to the Free Software
  20. **  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  21. */
  22.  
  23. /* Watcom C inline assembler versions of some functions added
  24.  * by Petteri Kangaslampi <pekanga@freeport.uwasa.fi>
  25. */
  26.  
  27. #ifndef FIXED_H_
  28. #define FIXED_H_
  29.  
  30. #include "limits.h"
  31.  
  32. /* fixed point conversions */
  33. #define INT_TO_FIXED(i) ((i) << 16)
  34. #define FIXED_TO_INT(f) ((f) >> 16)
  35. #define FIXED_TO_FLOAT(f) (((double) (f)) / 65536.0)
  36. #define FLOAT_TO_FIXED(f) ((fixed) (f * 65536.0))
  37.  
  38. /* functions */
  39. #define FIXED_ABS(f) ((f) < 0 ? -(f) : (f))
  40. #define FIXED_TRUNC(f) ((f) & 0xffff0000)
  41. #define FIXED_SIGN(f) ((unsigned int) (f) >> 31)
  42. #define FIXED_PRODUCT_SIGN(f, g) ((unsigned int) ((f) ^ (g)) >> 31)
  43. #define FIXED_HALF(f) ((f) / 2)
  44. #define FIXED_DOUBLE(f) ((f) << 1)
  45.  
  46. /* perform integer scaling of a fixed point number */
  47. #define FIXED_SCALE(f, i) ((f) * (i))
  48.  
  49.  
  50. /* fixed point constants */
  51. #define FIXED_ZERO     (INT_TO_FIXED(0))
  52. #define FIXED_ONE      (INT_TO_FIXED(1))
  53. #define FIXED_ONE_HALF (FIXED_HALF(FIXED_ONE))
  54. #define FIXED_PI       (FLOAT_TO_FIXED(3.14159265))
  55. #define FIXED_2PI      (FLOAT_TO_FIXED(6.28318531))
  56. #define FIXED_HALF_PI  (FLOAT_TO_FIXED(1.57079633))
  57. #define FIXED_MIN      LONG_MIN
  58. #define FIXED_MAX      LONG_MAX
  59.  
  60. /* we need this for kludges to avoid fixed point division overflow */
  61. #define FIXED_EPSILON  ((fixed) 0x100)
  62.  
  63. #define MIN(a, b) ((a) < (b) ? (a) : (b))
  64. #define MAX(a, b) ((a) > (b) ? (a) : (b))
  65.  
  66. typedef long fixed;
  67.  
  68. extern fixed fix_sqrt(fixed);
  69.  
  70.  
  71. #if defined(__GNUC__) && defined(ARCH_i86)
  72. static inline fixed fixmul(fixed r1, fixed r2)
  73. {
  74.      fixed result;
  75.  
  76.      __asm__ ("imull %2\n\t"
  77.           "shrd  $16, %%edx, %%eax\n\t"
  78.           :"=a" (result):"a" (r1), "d" (r2):"eax", "edx");
  79.  
  80.      return result;
  81. }
  82.  
  83.  
  84. static inline fixed fixmul2_30(fixed r1, fixed r2)
  85. {
  86.      fixed result;
  87.  
  88.      __asm__ ("imull %2\n\t"
  89.           "shrd  $30, %%edx, %%eax\n\t"
  90.           :"=a" (result):"a" (r1), "d" (r2):"eax", "edx");
  91.  
  92.      return result;
  93. }
  94.  
  95.  
  96. static inline fixed fixdiv(fixed dividend, fixed divisor)
  97. {
  98.      fixed result;
  99.  
  100.      if (divisor == FIXED_ZERO)
  101.       fatal_error("divide by zero");
  102.  
  103.      /* no checking for overflow is done yet */
  104.      __asm__("movl %%edx, %%eax\n\t"
  105.          "sar  $16, %%edx\n\t"
  106.          "shl  $16, %%eax\n\t"
  107.          "idivl %%ecx, %%eax\n\t"
  108.          :"=a" (result):"d" (dividend), "c" (divisor):"eax", "ecx", "edx");
  109.  
  110.      return result;
  111. }
  112.  
  113. #else
  114.  
  115. #ifdef __WATCOMC__
  116.  
  117. fixed fixmul(fixed r1, fixed r2);
  118. #pragma aux fixmul = \
  119.     "   imul    edx"            \
  120.     "   shrd    eax,edx,16"     \
  121.     parm [eax] [edx] \
  122.     modify exact [eax edx] \
  123.     value [eax];
  124.  
  125. fixed fixmul2_30(fixed r1, fixed r2);
  126. #pragma aux fixmul2_30 = \
  127.     "   imul    edx"            \
  128.     "   shrd    eax,edx,30 "    \
  129.     parm [eax] [edx] \
  130.     modify exact [eax edx] \
  131.     value [eax];
  132.  
  133. fixed fixdiv(fixed dividend, fixed divisor);
  134. #pragma aux fixdiv = \
  135.     "   mov     edx,eax"        \
  136.     "   sar     edx,16"         \
  137.     "   shl     eax,16"         \
  138.     "   idiv    ecx"            \
  139.     parm [eax] [ecx] \
  140.     modify exact [eax edx] \
  141.     value [eax];
  142.  
  143. #else
  144.  
  145. #define fixmul(a, b) ((fixed) (((double) (a) * (double) (b)) / 65536.0))
  146. #define fixmul2_30(a, b) ((fixed) (((double) (a) * (double) (b)) / \
  147.                    1073741824.0))
  148. #define fixdiv(a, b) ((fixed) (((double) (a) / (double) (b)) * 65536.0))
  149.  
  150. #endif
  151. #endif
  152.  
  153. #endif /* _FIXED_H_ */
  154.